﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Xml.Linq;
using System.Linq;
using System.Collections.Generic;
using System.IO.IsolatedStorage;
using System.IO;
using System.Collections;

namespace ActivityTracker.Library
{
    public class RunningActivity
    {
        #region Global

        IsolatedStorageFile isoStore = IsolatedStorageFile.GetUserStoreForApplication();
        IsolatedStorageFileStream isoStream;
        XDocument xdoc;

        #endregion

        //Saving Running Activity
        public void SaveRunningActivity(string actId, string actName, string actStartDate, string actStartTime, string lapStartTime, List<LapProp> objLapList)
        {
            try
            {
                if (!isoStore.FileExists("ActivityTracker/RunningActivity.xml"))
                    SaveRunningActivityRootElement();
                SaveRunningActivityElement(actId, actName, actStartDate, actStartTime, lapStartTime, objLapList);
            }
            catch (Exception ex)
            {
                Exception exNew = new Exception("Exception in SaveRunningActivity Method In ActivityTracker.Library.Activity.RunningActivity file\n\n" + ex.Message + " \n\n Stack Trace \n" + ex.StackTrace);
                foreach (DictionaryEntry d in ex.Data)
                    exNew.Data.Add(d.Key, d.Value);
                throw exNew;
            }
        }

        private void SaveRunningActivityRootElement()
        {
            try
            {
                //Saving Root Element For First Time
                if (!isoStore.FileExists("ActivityTracker/RunningActivity.xml"))
                {
                    isoStream = new IsolatedStorageFileStream("ActivityTracker/RunningActivity.xml", FileMode.Create, isoStore);
                    xdoc = new XDocument(new XDeclaration("1.0", "utf-8", "yes"),
                        new XElement("runningactivity"));
                    xdoc.Save(isoStream);
                    isoStream.Close();
                }
            }
            catch (Exception ex)
            {
                Exception exNew = new Exception("Exception in SaveRunningActivityRootElement Method In ActivityTracker.Library.Activity.RunningActivity file\n\n" + ex.Message + " \n\n Stack Trace \n" + ex.StackTrace);
                throw exNew;
            }
        }

        private void SaveRunningActivityElement(string actId, string actName, string actStartDate, string actStartTime, string lapStartTime, List<LapProp> objLapList)
        {
            try
            {
                isoStream = new IsolatedStorageFileStream("ActivityTracker/RunningActivity.xml", FileMode.Open, isoStore);
                xdoc = XDocument.Load(isoStream);
                isoStream.Close();

                //Remove if already saved
                RemoveSavedRunningActivity(actId, actName, actStartDate, actStartTime);

                //getting last running id
                int runId = getLastRunningActivityId(ref xdoc);
                runId += 1;

                //creating laps element
                XElement laps = new XElement("laps");
                foreach (LapProp lp in objLapList)
                {
                    laps.Add(new XElement(lp.LapNo.Replace(" ", "")));
                    laps.Element(lp.LapNo.Replace(" ", "")).Add(new XAttribute("lapno", lp.LapNo), new XAttribute("laptime", lp.LapTime));
                }

                //save element
                xdoc.Root.Add(new XElement("activity", new XAttribute("runId", runId),
                        new XElement("actId", actId),
                        new XElement("actName", actName),
                        new XElement("actStartDate", actStartDate),
                        new XElement("actStartTime", actStartTime),
                        new XElement("lapStartTime", lapStartTime),
                        new XElement(laps)));

                isoStream = new IsolatedStorageFileStream("ActivityTracker/RunningActivity.xml", FileMode.Create, isoStore);
                xdoc.Save(isoStream);
                isoStream.Close();
            }
            catch (Exception ex)
            {
                Exception exNew = new Exception("Exception in SaveRunningActivityElement Method In ActivityTracker.Library.Activity.RunningActivity file\n\n" + ex.Message + " \n\n Stack Trace \n" + ex.StackTrace);
                exNew.Data.Add("actId_SaveRunningActivityElement", actId);
                exNew.Data.Add("actName_SaveRunningActivityElement", actName);
                exNew.Data.Add("actStartDate_SaveRunningActivityElement", actStartDate);
                exNew.Data.Add("actStartTime_SaveRunningActivityElement", actStartTime);
                exNew.Data.Add("lapStartTime_SaveRunningActivityElement", lapStartTime);
                foreach (LapProp lp in objLapList)
                    exNew.Data.Add(lp.LapNo, lp.LapTime);
                throw exNew;
            }
        }

        public void RemoveSavedRunningActivity(string actId, string actName, string actStartDate, string actStartTime)
        {

            var ele = from f in xdoc.Descendants("activity")
                      where (f.Element("actId").Value == actId) && (f.Element("actStartDate").Value == actStartDate) && (f.Element("actStartTime").Value == actStartTime)
                      select f;
            foreach (var el in ele)
            {
                el.Remove();
                isoStream = new IsolatedStorageFileStream("ActivityTracker/RunningActivity.xml", FileMode.Create, isoStore);
                xdoc.Save(isoStream);
                isoStream.Close();
                break;
            }
        }

        private int getLastRunningActivityId(ref XDocument xdoc)
        {
            int runId = 0;
            try
            {
                var DescendingList = from i in xdoc.Descendants("activity") orderby Convert.ToInt32(i.Attribute("runId").Value) descending select i;
                foreach (var ele in DescendingList)
                {
                    runId = Convert.ToInt32(ele.Attribute("runId").Value);
                    break;
                }
            }
            catch (Exception ex)
            {
                Exception exNew = new Exception("Exception in getLastRunningActivityId Method In ActivityTracker.Library.Activity.RunningActivity file\n\n" + ex.Message + " \n\n Stack Trace \n" + ex.StackTrace);
                throw exNew;
            }
            return runId;
        }

        //Loading Running Activity
        public ActivityProp LoadRunningActivity(out int lapCount, out List<LapProp> objLapList)
        {
            lapCount = 0;
            objLapList = new List<LapProp>();
            ActivityProp RunningActivity = new ActivityProp();
            try
            {
                if (isoStore.FileExists("ActivityTracker/RunningActivity.xml"))
                {
                    isoStream = new IsolatedStorageFileStream("ActivityTracker/RunningActivity.xml", FileMode.Open, isoStore);
                    xdoc = XDocument.Load(isoStream);
                    isoStream.Close();

                    //getting last running id
                    int runId = getLastRunningActivityId(ref xdoc);
                    var lastRunningAct = from f in xdoc.Descendants("activity") where f.Attribute("runId").Value == runId.ToString() select f;
                    foreach (XElement ele in lastRunningAct)
                    {
                        RunningActivity.ActId = ele.Element("actId").Value;
                        RunningActivity.ActName = ele.Element("actName").Value;
                        RunningActivity.ActStartDate = ele.Element("actStartDate").Value;
                        RunningActivity.ActStartTime = ele.Element("actStartTime").Value;
                        RunningActivity.ActLapStartTime = ele.Element("lapStartTime").Value;

                        var laps = from ll in ele.Descendants("laps") select ll;
                        lapCount = laps.Elements().Count();
                        foreach (XElement lapele in laps.Elements().OrderByDescending(x => x.Attribute("lapno").Value))
                        {
                            LapProp lp = new LapProp();
                            lp.LapNo = lapele.Attribute("lapno").Value;
                            lp.LapTime = lapele.Attribute("laptime").Value;
                            objLapList.Add(lp);
                        }
                        break;
                    }
                }
            }
            catch (Exception ex)
            {
                Exception exNew = new Exception("Exception in LoadRunningActivity Method In ActivityTracker.Library.Activity.RunningActivity file\n\n" + ex.Message + " \n\n Stack Trace \n" + ex.StackTrace);
                throw exNew;
            }
            return RunningActivity;
        }
    }
}
